package com.song.uaa.gateway.web.rest;

import java.util.Map;

import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
import org.springframework.security.oauth2.core.oidc.OidcIdToken;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.server.WebSession;
import reactor.core.publisher.Mono;

/**
 * 退出
 */
@RestController
public class LogoutResource {

    private final Mono<ClientRegistration> registration;

    public LogoutResource(ReactiveClientRegistrationRepository registrations) {
        this.registration = registrations.findByRegistrationId("oidc");
    }

    /**
     * 注销当前用户。
     */
    @PostMapping("/api/logout")
    public Mono<Map<String, String>> logout(@AuthenticationPrincipal(expression = "idToken") OidcIdToken idToken,
                                            ServerHttpRequest request,
                                            WebSession session) {
        return session.invalidate()
                .then(
                        this.registration.map(oidc -> prepareLogoutUri(request, oidc, idToken))
                );
    }

    /**
     * 获取注销令牌URL
     */
    private Map<String, String> prepareLogoutUri(ServerHttpRequest request,
                                                 ClientRegistration clientRegistration,
                                                 OidcIdToken idToken) {
        StringBuilder logoutUrl = new StringBuilder();
        logoutUrl.append(
                clientRegistration
                        .getProviderDetails()
                        .getConfigurationMetadata()
                        .get("end_session_endpoint")
                        .toString()
        );
        String originUrl = request.getHeaders().getOrigin();
        logoutUrl.append("?id_token_hint=")
                .append(idToken.getTokenValue())
                .append("&post_logout_redirect_uri=")
                .append(originUrl);
        return Map.of("logoutUrl", logoutUrl.toString());
    }
}
